package com.globalwave.datasync.engine;

import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set;

import com.globalwave.common.db.ConnectionProvider;
import com.globalwave.datasync.SyncConfigLoader;

public abstract class BaseBatchSync extends BaseSync {


	
	public BaseBatchSync(
			final String sourceDbCode, 
			final String syncConfigCode, 
			final ConnectionProvider connectionProvider)
	{
		config = SyncConfigLoader.getInstance().getConfig(sourceDbCode, syncConfigCode) ;

    	srcConnection = connectionProvider.getConnection(config.getSource().getDbCode()) ;
    	destConnection = connectionProvider.getConnection(config.getDestination().getDbCode()) ;
	}
	
	public void transfer() throws Exception {
		Long start = (Long)context.get("start") ;
    	ResultSet srcResultSet = 
	         queryResultSet(
	        		 srcConnection,
	        		 config.getSourceQuerySQL(),
	        		 new Object[]{start},
	        		 true) ;
    	
    	if (srcResultSet.next()) {// exist record to sync
        	final String fieldName = config.getSource().getKeys()[0].getSyncColumnsCode() ;
        	start = srcResultSet.getLong(fieldName) ;
        	
        	srcResultSet.last() ;
        	Long end = srcResultSet.getLong(fieldName) ;
        	Integer size = srcResultSet.getRow() ;
	    	Set<Long> existIds = getExistIds(start, end) ;
	    	
	    	srcResultSet.beforeFirst() ;
	        executeBatchInsert(srcResultSet, existIds, start, end, size) ;
	        context.put("end", end) ;
    	} else {
    		context.remove("end") ;
    	}
    	
    }
    
	private Set<Long> getExistIds(Long start, Long end) throws Exception {
		final Set<Long> result = new HashSet<Long>() ;
    	ResultSet srcResultSet = 
	         queryResultSet(
	        		 destConnection,
	        		 config.getDestinationQuerySQL(),
	        		 new Object[]{start, end}) ;
    	
    	final String fieldName = config.getDestination().getKeys()[0].getSyncColumnsCode() ;
    	
    	while (srcResultSet.next()) {
    		result.add(srcResultSet.getLong(fieldName)) ;
    	}
    	
		return result ;
	}
    /**
     * 数据同步处理，把数据集中的内容，同步到目标数据库
     * 
     * @param executeSQL 将要执行的SQL
     * @param srcResultSet 原数据集，只有一个数据记录，并当前指向该记录
     * @param dbKeyValues 数据库key值
     * 
     */
    protected abstract void executeBatchInsert(ResultSet srcResultSet, Set<Long> existIds, Long start, Long end, int size) throws Exception;
    
	  
}
